From 462495c1bf5f6b1cd999a409625268c934e180ea Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Thu, 26 Oct 2017 22:16:38 +0200 Subject: [PATCH] dax: Avoid ABI change in 4.13.5 Commit c3ca015fab6d ("dax: remove the pmem_dax_ops->flush abstraction") removed dax_operations::flush and target_type::dax_flush, resulting in an ABI change. Add these operations back but don't restore any of the calls to them. To keep existing callers working during an incomplete kernel upgrade, change all the implementations to directly do arch_wb_cache_pmem(), just as dax_flush() does in the new kernel. Don't change dax_flush() back; it shouldn't have any out-of-tree callers. Gbp-Pq: Topic debian Gbp-Pq: Name dax-avoid-abi-change-in-4.13.5.patch --- drivers/md/dm-linear.c | 10 ++++++++++ drivers/md/dm-stripe.c | 10 ++++++++++ drivers/md/dm.c | 10 ++++++++++ drivers/nvdimm/pmem.c | 7 +++++++ include/linux/dax.h | 2 ++ include/linux/device-mapper.h | 3 +++ 6 files changed, 42 insertions(+) diff --git a/drivers/md/dm-linear.c b/drivers/md/dm-linear.c index 208800610af..113fb2218a9 100644 --- a/drivers/md/dm-linear.c +++ b/drivers/md/dm-linear.c @@ -184,6 +184,15 @@ static size_t linear_dax_copy_from_iter(struct dm_target *ti, pgoff_t pgoff, return dax_copy_from_iter(dax_dev, pgoff, addr, bytes, i); } +static void linear_dax_flush(struct dm_target *ti, pgoff_t pgoff, void *addr, + size_t size) +{ +#ifdef CONFIG_ARCH_HAS_PMEM_API + void arch_wb_cache_pmem(void *addr, size_t size); + arch_wb_cache_pmem(addr, size); +#endif +} + static struct target_type linear_target = { .name = "linear", .version = {1, 4, 0}, @@ -198,6 +207,7 @@ static struct target_type linear_target = { .iterate_devices = linear_iterate_devices, .direct_access = linear_dax_direct_access, .dax_copy_from_iter = linear_dax_copy_from_iter, + .dax_flush = linear_dax_flush, }; int __init dm_linear_init(void) diff --git a/drivers/md/dm-stripe.c b/drivers/md/dm-stripe.c index 1690bb299b3..6cf0b1c29a2 100644 --- a/drivers/md/dm-stripe.c +++ b/drivers/md/dm-stripe.c @@ -458,6 +458,15 @@ static void stripe_io_hints(struct dm_target *ti, blk_limits_io_opt(limits, chunk_size * sc->stripes); } +static void stripe_dax_flush(struct dm_target *ti, pgoff_t pgoff, void *addr, + size_t size) +{ +#ifdef CONFIG_ARCH_HAS_PMEM_API + void arch_wb_cache_pmem(void *addr, size_t size); + arch_wb_cache_pmem(addr, size); +#endif +} + static struct target_type stripe_target = { .name = "striped", .version = {1, 6, 0}, @@ -472,6 +481,7 @@ static struct target_type stripe_target = { .io_hints = stripe_io_hints, .direct_access = stripe_dax_direct_access, .dax_copy_from_iter = stripe_dax_copy_from_iter, + .dax_flush = stripe_dax_flush, }; int __init dm_stripe_init(void) diff --git a/drivers/md/dm.c b/drivers/md/dm.c index eed539a4eec..673c16790c8 100644 --- a/drivers/md/dm.c +++ b/drivers/md/dm.c @@ -993,6 +993,15 @@ static size_t dm_dax_copy_from_iter(struct dax_device *dax_dev, pgoff_t pgoff, return ret; } +static void dm_dax_flush(struct dax_device *dax_dev, pgoff_t pgoff, void *addr, + size_t size) +{ +#ifdef CONFIG_ARCH_HAS_PMEM_API + void arch_wb_cache_pmem(void *addr, size_t size); + arch_wb_cache_pmem(addr, size); +#endif +} + /* * A target may call dm_accept_partial_bio only from the map routine. It is * allowed for all bio types except REQ_PREFLUSH. @@ -2980,6 +2989,7 @@ static const struct block_device_operations dm_blk_dops = { static const struct dax_operations dm_dax_ops = { .direct_access = dm_dax_direct_access, .copy_from_iter = dm_dax_copy_from_iter, + .flush = dm_dax_flush, }; /* diff --git a/drivers/nvdimm/pmem.c b/drivers/nvdimm/pmem.c index 88c12825876..f7099adaabc 100644 --- a/drivers/nvdimm/pmem.c +++ b/drivers/nvdimm/pmem.c @@ -243,9 +243,16 @@ static size_t pmem_copy_from_iter(struct dax_device *dax_dev, pgoff_t pgoff, return copy_from_iter_flushcache(addr, bytes, i); } +static void pmem_dax_flush(struct dax_device *dax_dev, pgoff_t pgoff, + void *addr, size_t size) +{ + arch_wb_cache_pmem(addr, size); +} + static const struct dax_operations pmem_dax_ops = { .direct_access = pmem_dax_direct_access, .copy_from_iter = pmem_copy_from_iter, + .flush = pmem_dax_flush, }; static const struct attribute_group *pmem_attribute_groups[] = { diff --git a/include/linux/dax.h b/include/linux/dax.h index 0d8f35f6c53..714e9a40bcf 100644 --- a/include/linux/dax.h +++ b/include/linux/dax.h @@ -19,6 +19,8 @@ struct dax_operations { /* copy_from_iter: required operation for fs-dax direct-i/o */ size_t (*copy_from_iter)(struct dax_device *, pgoff_t, void *, size_t, struct iov_iter *); + /* flush: should be unused */ + void (*flush)(struct dax_device *, pgoff_t, void *, size_t); }; extern struct attribute_group dax_attribute_group; diff --git a/include/linux/device-mapper.h b/include/linux/device-mapper.h index 17c378ecbbd..4f2b3b2076c 100644 --- a/include/linux/device-mapper.h +++ b/include/linux/device-mapper.h @@ -134,6 +134,8 @@ typedef long (*dm_dax_direct_access_fn) (struct dm_target *ti, pgoff_t pgoff, long nr_pages, void **kaddr, pfn_t *pfn); typedef size_t (*dm_dax_copy_from_iter_fn)(struct dm_target *ti, pgoff_t pgoff, void *addr, size_t bytes, struct iov_iter *i); +typedef void (*dm_dax_flush_fn)(struct dm_target *ti, pgoff_t pgoff, void *addr, + size_t size); #define PAGE_SECTORS (PAGE_SIZE / 512) void dm_error(const char *message); @@ -184,6 +186,7 @@ struct target_type { dm_io_hints_fn io_hints; dm_dax_direct_access_fn direct_access; dm_dax_copy_from_iter_fn dax_copy_from_iter; + dm_dax_flush_fn dax_flush; /* For internal device-mapper use. */ struct list_head list; -- 2.30.2